package com.h3c.nem.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.eos.common.util.CustomBeanUtils;
import com.eos.common.util.IdWorker;
import com.h3c.nem.async.AsyncSendMessage;
import com.h3c.nem.client.AbilityClient;
import com.h3c.nem.dto.OfferAdjustDTO;
import com.h3c.nem.dto.TbOfferWorkerDTO;
import com.h3c.nem.dto.form.ConfigTheFormSubmit;
import com.h3c.nem.dto.form.GetFormBusinessData;
import com.h3c.nem.dto.form.HistoryInfo;
import com.h3c.nem.entity.*;
import com.h3c.nem.enums.OfferModifyApprovalEnum;
import com.h3c.nem.mapper.TbOfferModifyMapper;
import com.h3c.nem.mapstruct.TbOfferWorkerMapstruct;
import com.h3c.nem.service.*;
import com.h3c.nem.utils.AppBusinessException;
import com.h3c.nem.utils.DateUtil;
import com.h3c.nem.vo.TbOfferStudyVO;
import com.h3c.nem.vo.TbWorkerExperienceVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * (TbOfferModify)表服务实现类
 *
 * @author makejava
 * @since 2022-06-09 09:36:33
 */
@Service
public class TbOfferModifyServiceImpl extends ServiceImpl<TbOfferModifyMapper, TbOfferModify> implements ITbOfferModifyService {

    @Resource
    private CommService commService;

    @Lazy
    @Resource
    private ITbOfferWorkerService iTbOfferWorkerService;

    @Resource
    private ITbFlowInstService iTbFlowInstService;

    @Autowired
    private ISdTodoTaskService iSdTodoTaskService;
    @Resource
    private AsyncSendMessage asyncSendMessage;
    @Resource
    private ISdNoticeRecordService iSdNoticeRecordService;
    @Resource
    private ITbWorkerExperienceService iTbWorkerExperienceService;
    @Resource
    private ITbOfferStudyService iTbOfferStudyService;
    @Resource
    private ITbApprovalRecordService approvalRecordService;
    @Resource
    private ISdDeptService sdDeptService;
    @Resource
    private AbilityClient abilityClient;

    @Override
    public String saveOfferModify(OfferAdjustDTO dto, TbOfferWorker worker) {

        TbOfferModify tbOfferModify = new TbOfferModify();
        tbOfferModify.setRecordId(IdWorker.nextId() + "");
        tbOfferModify.setWorkerId(dto.getWorkerId());
        tbOfferModify.setModifyReason(dto.getModifyReason());
        tbOfferModify.setModifyDate(new Date());
        tbOfferModify.setOperatorInfo(commService.getLoginUserNameAndId());
        tbOfferModify.setPostModifyType(dto.getPostModifyType());

        tbOfferModify.setAfterCompany(dto.getPersonnelRange());
        tbOfferModify.setAfterCompanyCode(dto.getPersonnelRangeCode());
        tbOfferModify.setAfterSubCompany(dto.getSubPersonnelRange());
        tbOfferModify.setAfterSubCompanyCode(dto.getSubPersonnelRangeCode());
        tbOfferModify.setAfterDeptName(dto.getDeptNameChain());
        tbOfferModify.setAfterPostId(dto.getPostId());
        tbOfferModify.setAfterPostName(dto.getPostName());
        tbOfferModify.setAfterWorkCity(dto.getWorkCity());
        tbOfferModify.setAfterOuterCity(dto.getOuterCity());

        tbOfferModify.setBeforeCompany(worker.getPersonnelRange());
        tbOfferModify.setBeforeCompanyCode(worker.getPersonnelRangeCode());
        tbOfferModify.setBeforeSubCompany(worker.getSubPersonnelRange());
        tbOfferModify.setBeforeSubCompanyCode(worker.getSubPersonnelRangeCode());
        tbOfferModify.setBeforeDeptName(worker.getDeptNameChain());
        tbOfferModify.setBeforePostId(worker.getPostId());
        tbOfferModify.setBeforePostName(worker.getPostName());
        tbOfferModify.setBeforeWorkCity(worker.getWorkCity());
        tbOfferModify.setBeforeOuterCity(worker.getOuterCity());

        save(tbOfferModify);
        return tbOfferModify.getRecordId();
    }

    @Override
    public JSONObject getOfferModifyInfo(String workerId, String recordId) {
        TbOfferWorker offerWorker = iTbOfferWorkerService.getById(workerId);
        TbOfferModify modify = getById(recordId);
        OfferAdjustDTO dto = TbOfferWorkerMapstruct.INSTANCE.entityToAdjustDto(modify);
        dto.setWorkerName(offerWorker.getWorkerName());
        dto.setBirthday(DateUtil.getDateStr(offerWorker.getBirthday()));
        dto.setSex(offerWorker.getSex());
        dto.setCertType(offerWorker.getCertType().getName());
        dto.setCertNo(offerWorker.getCertNo());
        dto.setEmail(offerWorker.getEmail());

        List<TbOfferStudyVO> list = iTbOfferStudyService.getStudyInfoByWorkerId(workerId);
        if (!CollectionUtils.isEmpty(list)) {
            List<TbOfferStudyVO> highestEducationList = list.stream().filter(TbOfferStudyVO::getIsHighestEducation).collect(Collectors.toList());
            if (!highestEducationList.isEmpty()) {
                TbOfferStudyVO studyVO = highestEducationList.get(0);
                dto.setCollegeName(studyVO.getCollegeName());
                dto.setMajorName(studyVO.getMajorName());
                dto.setEducation(studyVO.getEducation().getTypeName());
            }
        }
        return JSONObject.parseObject(JSON.toJSONString(dto));
    }

    @Override
    public Map<String, Object> getOfferModify(GetFormBusinessData formBusinessData) {
        Map<String, Object> result = new HashMap<>();
        String recordId = formBusinessData.getDocId();
        TbOfferModify offerModify = getById(recordId);
        String workerId = offerModify.getWorkerId();
        JSONObject jsonObject = getOfferModifyInfo(workerId, recordId);

        List<TbWorkerExperienceVO> experienceByWorkerId = iTbWorkerExperienceService.getWorkExperienceByWorkerId(workerId);
        jsonObject.put("workerExperienceList", experienceByWorkerId);
        List<TbOfferStudyVO> studyVOList = iTbOfferStudyService.getStudyInfoByWorkerId(workerId);
        jsonObject.put("offerStudyList", studyVOList);
        result.put("data", jsonObject);

        List<HistoryInfo> historyInfos = iTbFlowInstService.getHistoryInfosForPre(recordId);
        result.put("historyInfos", historyInfos);

        SdTodoTask todoTask = iSdTodoTaskService.getTodoTask(formBusinessData.getWorkFlowId(), recordId);
        String authorId = todoTask.getAuthorid();
        result.put("currentEmpNumber", authorId);
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void submitApproval(ConfigTheFormSubmit formSubmit) {
        JSONObject data = JSONObject.parseObject(StringUtils.isEmpty(formSubmit.getData())?"": formSubmit.getData());
        String buttonType = formSubmit.getButtonType();
        String currentNodeId = formSubmit.getCurrentNodeId();
        String docId = formSubmit.getDocId();
        TbOfferModify offerModify = getById(docId);
        Integer result = null;

        String opinion = "";
        switch (buttonType) {
            case "Agree": {
                result = 1;
                opinion = data.getString("opinion");
                if (OfferModifyApprovalEnum.OFFER_MODIFY_APPROVAL_CHRO.getNodeId().equals(currentNodeId)) {
                    TbOfferWorker worker = new TbOfferWorker();
                    worker.setWorkerId(offerModify.getWorkerId());
                    worker.setDeptNameChain(offerModify.getAfterDeptName());
                    iTbOfferWorkerService.setDeptName(worker);
                    LambdaUpdateWrapper<TbOfferWorker> updateWrapper = new UpdateWrapper<TbOfferWorker>().lambda();
                    if (!StringUtils.isEmpty(offerModify.getAfterCompany())) {
                        updateWrapper.set(TbOfferWorker::getPersonnelRange, offerModify.getAfterCompany())
                                .set(TbOfferWorker::getPersonnelRangeCode, offerModify.getAfterCompanyCode())
                                .set(TbOfferWorker::getSubPersonnelRange, offerModify.getAfterSubCompany())
                                .set(TbOfferWorker::getSubPersonnelRangeCode, offerModify.getAfterSubCompanyCode())
                                .set(TbOfferWorker::getWorkCity, offerModify.getAfterWorkCity())
                                .set(TbOfferWorker::getOuterCity, offerModify.getAfterOuterCity());
                    } else {
                        updateWrapper.set(TbOfferWorker::getDeptNameChain, offerModify.getAfterDeptName())
                                .set(TbOfferWorker::getPostId, offerModify.getAfterPostId())
                                .set(TbOfferWorker::getPostName, offerModify.getAfterPostName())
                                .set(TbOfferWorker::getDept1name, worker.getDept1name())
                                .set(TbOfferWorker::getDept2name, worker.getDept2name())
                                .set(TbOfferWorker::getDept3name, worker.getDept3name())
                                .set(TbOfferWorker::getDept4name, worker.getDept4name());
                    }
                    updateWrapper.eq(TbOfferWorker::getWorkerId, offerModify.getWorkerId());
                    iTbOfferWorkerService.update(updateWrapper);
                    iTbOfferWorkerService.updateOfferWorkerToSap(offerModify.getWorkerId());
                }
                OfferModifyApprovalEnum node = OfferModifyApprovalEnum.getNextNodeId(currentNodeId);
                SdNoticeRecord sdNoticeRecord = null;
                if (node != null) {
                    TbOfferWorker byId = iTbOfferWorkerService.getById(offerModify.getWorkerId());
                    TbOfferWorkerDTO dto = generateDTO(byId);
                    //不为最后环节
                    sdNoticeRecord = iSdNoticeRecordService.createOfferModifyRecord(offerModify.getRecordId(),
                            offerModify.getAfterDeptName(), "APPROVAL_OFFER_EMAIL", node.getStatus(), "", dto);
                    asyncSendMessage.sendMessage(Collections.singletonList(sdNoticeRecord));
                }

                OfferModifyApprovalEnum modifyApprovalEnum = OfferModifyApprovalEnum.getOfferEnumByNodeId(currentNodeId);
                String targetId = sdNoticeRecord == null ? "" : sdNoticeRecord.getTargetId();
                SdTodoTask todoTask = iSdTodoTaskService.createOfferModifyTodoTask(targetId, modifyApprovalEnum,
                        offerModify.getRecordId(), "N7", "预备员工offer信息修改审核", StringUtils.isEmpty(offerModify.getOperatorInfo())? "":offerModify.getOperatorInfo().split("/")[1], StringUtils.isEmpty(offerModify.getOperatorInfo())? "":offerModify.getOperatorInfo().split("/")[0]); //移动中台回调
                asyncSendMessage.onlySendTodoTask(Collections.singletonList(todoTask), false);
                break;
            }
            case "Reject": {
                result = 2;
                opinion = data.getString("opinion");
                SdTodoTask todoTask = iSdTodoTaskService.getTodoTask(formSubmit.getWorkFlowId(), docId);
                todoTask.setAuthorid("");
                todoTask.setAuthorname("");
                todoTask.setStatus("APPROVED");
                iSdTodoTaskService.getEndUserId(todoTask);
                asyncSendMessage.onlySendTodoTask(Collections.singletonList(todoTask), true);
                break;
            }
            case "Transfer": {
                result = 3;
                opinion = formSubmit.getOpinion();
                String receiver = formSubmit.getTargetReceiver();
                SdAllWorker transferTarget = commService.getWorkerIdByDomain(receiver);
                SdTodoTask todoTask = iSdTodoTaskService.getTodoTask(formSubmit.getWorkFlowId(), docId);
                todoTask.setAuthorid(receiver);
                if (transferTarget != null) {
                    todoTask.setAuthorname(transferTarget.getWorkerName());
                } else {
                    throw new AppBusinessException("当前转办的目标员工不能转办");
                }
                asyncSendMessage.onlySendTodoTask(Collections.singletonList(todoTask), true);

                SdNoticeRecord sdNoticeRecord = iSdNoticeRecordService.createOfferModifyRecord(offerModify.getRecordId(),
                        offerModify.getAfterDeptName(), "APPROVAL_OFFER_EMAIL", 50, transferTarget.getWorkerId(), null);
                asyncSendMessage.sendMessage(Collections.singletonList(sdNoticeRecord));
                break;
            }
        }

        //记录approval
        String empNumber = formSubmit.getEmpNumber();
        SdAllWorker empInfo = commService.getWorkerIdByDomain(empNumber);
        approvalRecordService.saveRecord(docId, OfferModifyApprovalEnum.getStatusByNodeId(currentNodeId), empInfo.getWorkerId(),
                empInfo.getWorkerName() + "/" + empInfo.getWorkerId(), opinion, result);
    }

    public TbOfferWorkerDTO generateDTO(TbOfferWorker offerWorker) {
        String directDeptId = offerWorker.getDirectDeptId();
        if (StringUtils.isEmpty(directDeptId)) {
            SdDept deptByNameChain = sdDeptService.getDeptByNameChain(offerWorker.getDeptNameChain());
            directDeptId = String.valueOf(deptByNameChain.getDeptId());
        }
        int i = Integer.parseInt(directDeptId);
        JSONObject ptDept = abilityClient.getPtDept(i);
        TbOfferWorkerDTO dto = new TbOfferWorkerDTO();
        CustomBeanUtils.copyProperties(offerWorker, dto);
        dto.setDeptSystem(ptDept.getString("deptSystem"));
        return dto;
    }

    @Override
    public boolean checkOfferModifyHavingApproving(String workerId) {
        List<TbOfferModify> list = getBaseMapper().checkOfferModifyHavingApproving(workerId);
        return !list.isEmpty();
    }
}

